import os
import time
import fcntl
import threading
import subprocess


class MP3Player (threading.Thread):
    done = False
    #daemon = True

    def __init__(self):
        threading.Thread.__init__(self)
        self.player = subprocess.Popen(['mpg123', '-q', '-R', '--preload', '0.1'],
                                       shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
        self.song = ''
        self.cur_seconds = 0.0
        self.total_seconds = 0.0
        self.volume = 20.0
        self.status = 'INIT'

    def pipe_read(self, pipe):
        fd = pipe.fileno()
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
        try:
            pipe.flush()
            ba = pipe.readline()
            s = ba.decode()
            return s
        except:
            return ''

    def player_cmd(self, cmd):
        cmd += '\n'
        self.player.stdin.write(cmd.encode())
        self.player.stdin.flush()

    def is_playing(self):
        return self.status == 'PLAY'

    def load(self, file):
        self.song = file
        self.status = 'LOAD'
        self.player_cmd('LOADPAUSED ' + file)
        self.set_volume(self.volume)

    def play(self):
        self.status = 'PLAY'
        self.player_cmd('PAUSE')

    def stop(self):
        self.status = 'STOP'
        self.player_cmd('STOP')

    def quit(self):
        self.done = True

    def set_volume(self, vol):
        self.volume = vol
        self.player_cmd('VOLUME ' + str(vol))

    def get_status(self):
        return self.status

    def get_total_seconds(self):
        return self.total_seconds

    def get_current_seconds(self):
        return self.cur_seconds

    def set_current_seconds(self, seconds):
        self.player_cmd('JUMP ' + str(seconds) + 's')
        return self.cur_seconds

    def parse(self, cmd, value):
        if cmd == '@F':
            cur_frame,  frames_left, cur_seconds, seconds_left = value.split()
            cur_seconds = float(cur_seconds)
            seconds_left = float(seconds_left)
            self.cur_seconds = cur_seconds
            self.total_seconds = cur_seconds + seconds_left
        elif cmd == '@P':
            if value == '0':
                self.status = 'STOP'
            elif value == '1':
                self.status = 'PAUSE'
            else:
                self.status = 'PLAY'

    def run(self):
        # Run your code here
        print('Start Player Thread')
        while not self.done:
            while True:
                s = self.pipe_read(self.player.stdout)
                if len(s) > 0:
                    cmd, value = s.split(' ', 1)
                else:
                    break
                self.parse(cmd, value)

            time.sleep(0.1)
        print('Player Stop!!')

